#include "GL/glut.h"
#include "include/Grid.h"


int iWidth = 800;
int iHeight = 600;

#define COLS 50
#define ROWS 50

Grid grid(COLS,ROWS);

unsigned int szybkosc = 100;
bool gamePaused = 0;
bool fredkin = 0;
int wzor = 0;

int specialKey;

void changeSize(int w, int h)
{
	// Prevent a divide by zero, when window is too short
	// (you cant make a window of zero width).
	if(h == 0)
		h = 1;

   float ratio = 1.0* iWidth / iHeight;

	// Reset the coordinate system before modifying
	glViewport(0,0,iWidth,iHeight);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(0,iWidth,0,iHeight,-100,100);
   glMatrixMode(GL_MODELVIEW);
   glEnable(GL_POINT_SMOOTH);
}

void renderScene(void)
{
   if(!gamePaused)
      grid.nextFrame(fredkin);

   int cellSizeX = iWidth/COLS;
   int cellSizeY = iHeight/ROWS;

   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glPushMatrix();

   for (int i = 0; i < COLS ; i++)
   {
      for (int j = 0 ; j < ROWS ; j++)
      {
         if (grid.checkPoint(i,j) == true)
         {
            glColor3f(1.0f,1.0f,0.0f); // Change color to yellow
         }
         else
         {
            glColor3f(0.0f,0.0f,0.0f); // Change color to yellow
         }

         glBegin(GL_QUADS);
            glVertex2f(i*cellSizeX-0.35*cellSizeX, iHeight-(j*cellSizeY+0.35*cellSizeY));				// Top Left
            glVertex2f(i*cellSizeX+0.35*cellSizeX, iHeight-(j*cellSizeY+0.35*cellSizeY));				// Top Right
            glVertex2f(i*cellSizeX+0.35*cellSizeX, iHeight-(j*cellSizeY-0.35*cellSizeY));				// Bottom Right
            glVertex2f(i*cellSizeX-0.35*cellSizeX, iHeight-(j*cellSizeY-0.35*cellSizeY));
         glEnd();
      }
   }

   glPopMatrix();
   glutSwapBuffers();
   Sleep(szybkosc);
}

void processMouse(int button, int state, int x, int y) {

	specialKey = glutGetModifiers();

	if ((state == GLUT_DOWN))
	{
		if (button == GLUT_LEFT_BUTTON)
		{
		  // y = iHeight - y;

		   int cellSizeX = iWidth/COLS;
         int cellSizeY = iHeight/ROWS;

		   grid.changePoint(x/cellSizeX,y/cellSizeY);
		}
		else if (button == GLUT_MIDDLE_BUTTON)
		{
		}
		else
		{
		   int cellSizeX = iWidth/COLS;
         int cellSizeY = iHeight/ROWS;

         if(wzor == 0){
            grid.changePoint(x/cellSizeX,y/cellSizeY+1);
            grid.changePoint(x/cellSizeX+1,y/cellSizeY+2);
            grid.changePoint(x/cellSizeX+2,y/cellSizeY);
            grid.changePoint(x/cellSizeX+2,y/cellSizeY+1);
            grid.changePoint(x/cellSizeX+2,y/cellSizeY+2);
         }
         if(wzor == 1){
            grid.changePoint(x/cellSizeX,y/cellSizeY);
            grid.changePoint(x/cellSizeX+1,y/cellSizeY+1);
            grid.changePoint(x/cellSizeX,y/cellSizeY+1);
            grid.changePoint(x/cellSizeX+1,y/cellSizeY);
         }
         if(wzor == 2){
            grid.changePoint(x/cellSizeX,y/cellSizeY);
            grid.changePoint(x/cellSizeX,y/cellSizeY+1);
            grid.changePoint(x/cellSizeX,y/cellSizeY-1);
         }

		   /*grid[0][1] = true;
         grid[1][2] = true;
         grid[2][0] = true;
         grid[2][1] = true;
         grid[2][2] = true;*/
		}
	}
}

void processMouseActiveMotion(int x, int y)
{
	if (specialKey != GLUT_ACTIVE_ALT)
	{
	}
}

void processMousePassiveMotion(int x, int y)
{
}

void processMouseEntry(int state)
{
	if (state == GLUT_LEFT)
	{}

}

void processNormalKeys(unsigned char key, int x, int y) {

	switch(key)
	{
      case 27: // Esc
      {
         exit(0);
         break;
      }
      case '1':
      {
         wzor = 0;
         break;
      }
      case '2':
      {
         wzor = 1;
         break;
      }
      case '3':
      {
         wzor = 2;
         break;
      }
      case '+':
      {
         if(szybkosc > 25)
            szybkosc -= 25;
         break;
      }
      case '-':
      {
         if(szybkosc < 1000)
            szybkosc += 25;
         break;
      }
      case 'f':
      case 'F':
      {
         fredkin = !fredkin;
         break;
      }
      case 32: // Space
         gamePaused = !gamePaused;
         break;

   }
}

int main(int argc, char **argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(50,25);
	glutInitWindowSize(iWidth,iHeight);
	glutCreateWindow("Game of Life");
	glutDisplayFunc(renderScene);
	glutIdleFunc(renderScene);
	glutReshapeFunc(changeSize);
	glutKeyboardFunc(processNormalKeys);

	//adding here the mouse processing callbacks
	glutMouseFunc(processMouse);
	glutMotionFunc(processMouseActiveMotion);
	glutPassiveMotionFunc(processMousePassiveMotion);
	glutEntryFunc(processMouseEntry);
	glutMainLoop();
}
